import { memo, useCallback, useEffect, useState } from 'react';
import type { FC, PropsWithChildren } from 'react';
import { Link } from 'react-router-dom';
import {
  Avatar,
  Badge,
  Button,
  Card,
  Comment,
  Dropdown,
  Input,
  Menu,
  Modal,
  Pagination,
  Popover,
  Skeleton,
  Spin,
} from 'antd';
import { TextAreaProps } from 'antd/es/input';
import { API_BASEURL } from '@/constants/api';
import {
  resAddDynamicComment,
  resDeleteDynamic,
  resDynamicComment,
  resReplyDynamicComment,
} from '@/services/dynamic';
import {
  MessageOutlined,
  MessageTwoTone,
  MoreOutlined,
} from '@ant-design/icons';
import { usePagination, useRequest, useToggle } from 'ahooks';
import classNames from 'classnames';
import { paginationStyle } from '@/pages/UserPage/GoodsList';
import { createHtml, formatTime } from '@/utils/format';
import './index.scss';

const DynamicItem: FC<
  PropsWithChildren<{
    data: API.DynamicStruct;
    onEdit?: (defaultValue: API.DynamicStruct) => void;
    showTool?: boolean;
    onDelete?: (id: number) => void;
  }>
> = ({ data, onEdit, showTool = true, onDelete }) => {
  const {
    data: comments,
    loading,
    pagination,
  } = usePagination(
    ({ current, pageSize }) => {
      return resDynamicComment(data.id, {
        current,
        pageSize,
      });
    },
    { defaultPageSize: 5 }
  );
  const refresh = () => {
    pagination.onChange(pagination.current, pagination.pageSize);
  };
  const menu = (
    <Menu
      items={[
        {
          key: 'edit',
          label: <span className={'text-xs text-center'}>编辑</span>,
          onClick: () => {
            onEdit && onEdit(data);
          },
        },
        {
          key: 'delete',
          label: <span className={'text-xs text-center'}>删除</span>,
          onClick: () => {
            Modal.confirm({
              title: '删除动态',
              content: '确认要删除当前动态吗？',
              okText: '确定',
              okType: 'danger',
              cancelText: '取消',
              onOk() {
                onDelete && onDelete(data.id);
              },
            });
          },
        },
      ]}
    />
  );
  const title = (
    <div className={'flex items-start'}>
      <Avatar src={API_BASEURL + '/' + data.user.avatar} />
      <div className={'ml-2'}>
        <div className={'font-bold text-base'}>{data.user.name}</div>
        <div className={'text-xs text-gray-500'}>
          {formatTime(data.updated_at)}
        </div>
      </div>
    </div>
  );
  const extra = (
    <Dropdown overlay={menu} trigger={['click']} placement="bottom">
      <MoreOutlined rotate={90} />
    </Dropdown>
  );

  const [comment, setComment] = useState('');
  const { loading: addCommentLoading, runAsync } = useRequest(
    resAddDynamicComment,
    { manual: true }
  );

  const autoSize: TextAreaProps['autoSize'] = { minRows: 2, maxRows: 6 };
  const [reply, setReply] = useState('');

  const { runAsync: ReplyDynamicComment, loading: ReplyDynamicCommentLoading } =
    useRequest(resReplyDynamicComment, { manual: true });

  const [showDescription, { toggle: toggleShowDesc, set: setShowDesc }] =
    useToggle(false);
  const [needMore, { toggle: toggleNeedMore, set: setNeedMore }] =
    useToggle(false);
  const [height, setHeight] = useState<{ height: number; lineHeight: number }>({
    height: 0,
    lineHeight: 0,
  });
  const measuredRef = useCallback((node) => {
    if (node !== null) {
      setHeight({
        height: node.getBoundingClientRect().height,
        lineHeight: parseInt(
          document?.defaultView?.getComputedStyle(node).lineHeight || '21'
        ),
      });
    }
  }, []);

  useEffect(() => {
    if (
      height.lineHeight &&
      height.height &&
      height.height >= height.lineHeight * 4
    ) {
      setShowDesc(false);
      setNeedMore(true);
    }
  }, [height]);

  return (
    <Badge.Ribbon
      text={
        showDescription || needMore ? (
          <span
            onClick={() => {
              toggleShowDesc();
              toggleNeedMore();
            }}
            className={'cursor-pointer font-serif'}
          >
            {needMore ? '展开更多' : '收起更多'}
          </span>
        ) : null
      }
    >
      <Card
        hoverable
        title={title}
        extra={showTool ? extra : null}
        actions={[
          <div className={'px-16 flex'}>
            <Input
              placeholder={'评论'}
              value={comment}
              onChange={(e) => {
                setComment(e.target.value);
              }}
              size={'small'}
            />
            <div className={'ml-2'}>
              <Button
                size={'small'}
                disabled={!comment}
                loading={addCommentLoading}
                onClick={() => {
                  runAsync(data.id, { content: comment }).then(() => {
                    setComment('');
                    refresh();
                  });
                }}
                icon={<MessageTwoTone twoToneColor={'#cbd5e1'} />}
              />
            </div>
          </div>,
        ]}
      >
        <Card.Meta
          title={data.title}
          description={
            <div
              ref={measuredRef}
              className={classNames('w-[756px] text-gray-700', {
                'truncate-4 mb-2': !showDescription,
              })}
              dangerouslySetInnerHTML={createHtml(data.content)}
            />
          }
        />
        <Skeleton loading={loading} active avatar round>
          {comments &&
            comments.list.length > 0 &&
            comments.list.map((value) => (
              <Comment
                key={value.id}
                actions={
                  showTool
                    ? [
                        <Popover
                          content={
                            <div className={'flex space-x-2 w-[300px]'}>
                              <Input.TextArea
                                value={reply}
                                onChange={(e) => {
                                  setReply(e.target.value);
                                }}
                                autoSize={autoSize}
                                placeholder={'回复内容'}
                              />
                              <Button
                                loading={ReplyDynamicCommentLoading}
                                onClick={() => {
                                  ReplyDynamicComment(value.id, { reply }).then(
                                    () => {
                                      setReply('');
                                      refresh();
                                    }
                                  );
                                }}
                                icon={<MessageOutlined />}
                              />
                            </div>
                          }
                          placement={'right'}
                          title={'回复评论'}
                          trigger={'click'}
                        >
                          <span className={'text-xs'}>回复</span>
                        </Popover>,
                      ]
                    : undefined
                }
                content={<div className={'text-xs'}>{value.content}</div>}
                author={
                  <Link to={'/user_page/' + value.user_id}>
                    {value.user.name}
                  </Link>
                }
                datetime={<div>{formatTime(value.created_at)}</div>}
                avatar={
                  <Avatar src={API_BASEURL + '/' + value.user?.avatar} alt="" />
                }
              >
                {value.reply && (
                  <Comment
                    content={<div className={'text-xs'}>{value.reply}</div>}
                    author={
                      <Link to={'/user_page/' + value.user_id}>
                        {value.user.name}
                      </Link>
                    }
                    datetime={<div>{formatTime(value.created_at)}</div>}
                    avatar={
                      <Avatar
                        size={'small'}
                        src={API_BASEURL + '/' + value.user?.avatar}
                        alt=""
                      />
                    }
                  />
                )}
              </Comment>
            ))}
          {pagination.totalPage > 1 && (
            <Pagination
              current={pagination.current}
              pageSize={pagination.pageSize}
              total={comments?.total}
              onChange={pagination.onChange}
              onShowSizeChange={pagination.onChange}
              style={paginationStyle}
              size={'small'}
            />
          )}
        </Skeleton>
      </Card>
    </Badge.Ribbon>
  );
};

export default memo(DynamicItem);
